local shenji = fk.CreateSkill{
  name = "kl__shenji",
  tags = { Skill.Permanent },
}

shenji:addEffect("active", {
  prompt = "#kl__shenji",
  interaction = function(self, player)
    local choices = { "kl__shenji-skill" }
    local all_names = table.filter(Fk:getAllCardNames("b"), function(name)
      return Fk:cloneCard(name).trueName == "slash"
    end)
    table.insertTable(choices, player:getViewAsCardNames(shenji.name, all_names))
    return UI.ComboBox { choices = choices }
  end,
  max_card_num = 1,
  target_num = 1,
  card_filter = function(self, player, to_select, selected)
    if self.interaction.data == nil then return false end
    if self.interaction.data ~= "kl__shenji-skill" then
      return #selected == 0 and to_select
    end
  end,
  target_filter = function(self, player, to_select, selected, selected_cards)
    if self.interaction.data == nil then return false end
    if self.interaction.data == "kl__shenji-skill" then
      return #selected == 0 and #to_select:getSkillNameList() > 0
    else
      local to_use = Fk:cloneCard(self.interaction.data)
      to_use.subcards = selected_cards
      to_use.skillName = shenji.name
      if (#selected == 0 or to_use.multiple_targets) and player:isProhibited(to_select, to_use) then
        return false
      end
      return to_use.skill:targetFilter(player, to_select, selected, selected_cards, to_use)
    end
  end,
  feasible = function(self, player, selected, selected_cards)
    if self.interaction.data == nil then return false end
    if self.interaction.data ~= "kl__shenji-skill" then
      if #selected_cards ~= 1 then return false end
      local to_use = Fk:cloneCard(self.interaction.data)
      to_use.skillName = shenji.name
      to_use.subcards = selected_cards
      return to_use.skill:feasible(player, selected, selected_cards, to_use)
    else
      return #selected == 1 and #selected_cards == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = effect.from
    if self.interaction.data == nil then return false end
    if self.interaction.data == "kl__shenji-skill" then
      local target = effect.tos[1]
      local skills = table.filter(target:getSkillNameList(), function (s)
        return not player:hasSkill(s, true)
      end)
      local all_names = table.filter(Fk:getAllCardNames("b"), function(name)
        return Fk:cloneCard(name).trueName == "slash"
      end)
      if #skills > 0 then
        local chosen = room:askToChoice(player, {
          choices = skills,
          skill_name = shenji.name,
          prompt = "神技：选择其的一个技能当杀使用！",
          detailed = true,
        })
        if chosen then
          local use = room:askToUseVirtualCard(player, {
            name = all_names,
            skill_name = shenji.name,
            prompt = "神技：选择一种杀对一名角色使用",
            extra_data = {
              bypass_distances = true,
              bypass_times = true,
            },
            cancelable = false,
            skip = true,
          })
          if use then
            use.extra_data = use.extra_data or {}
            use.extra_data.kl_shenji_skill = {
              target = target,
              skill = chosen,
            }
            room:sendLog{
              type = "%to的技能【%arg】被 %from 当作 %arg2 使用了！",
              from = player.id,
              to = {target.id},
              arg = chosen,
              arg2 = use.card:toLogString(),
            }
            room:useCard(use)
          end
        end
      end
    else
      local card = Fk:cloneCard(self.interaction.data)
      card:addSubcard(effect.cards[1])
      card.skillName = shenji.name
      local use = {
        from = player,
        tos = effect.tos,
        card = card,
      }
      room:useCard(use)
    end
  end,
})

shenji:addEffect(fk.AfterCardUseDeclared, {
  can_refresh = function (self, event, target, player, data)
    return data.extra_data and data.extra_data.kl_shenji_skill
  end,
  on_refresh = function (self, event, target, player, data)
    local skill = data.extra_data.kl_shenji_skill.skill
    local to = data.extra_data.kl_shenji_skill.target
    player.room:handleAddLoseSkills(to, "-"..skill)
  end,
})


local shenji__TriggerViewAsCanTrigger = function(self, event, target, player, data)
  return target == player and player:hasSkill(shenji.name) and data.pattern and Exppattern:Parse(data.pattern):matchExp("slash")
end

local shenji__TriggerViewAsOnCost = function(self, event, target, player, data)
  local all_names = table.filter(Fk:getAllCardNames("b"), function(name)
    return Fk:cloneCard(name).trueName == "slash"
  end)
  local names = {}
  for _, name in ipairs(all_names) do
    local card = Fk:cloneCard(name)
    if Exppattern:Parse(data.pattern):match(card) then
      table.insertIfNeed(names, name)
    end
  end
  if #names > 0 then
    local name = names[1]
    if #names > 1 then
      name = table.every(names, function(str) return string.sub(str, -5) == "slash" end) and "slash" or "basic"
    end
    if player.room:askToSkillInvoke(player, { skill_name = shenji.name, prompt = "#mou__rende-invoke:::" .. name }) then
      event:setCostData(self, names)
      return true
    end
  end
end

shenji:addEffect(fk.AskForCardUse, {
  mute = true,
  can_trigger = shenji__TriggerViewAsCanTrigger,
  on_cost = shenji__TriggerViewAsOnCost,
  on_use = function(self, event, target, player, data)
    ---@type string
    local skillName = shenji.name
    local room = player.room
    local names = event:getCostData(self)
    local extra_data = data.extraData
    local isAvailableTarget = function(card, p)
      if extra_data then
        if type(extra_data.must_targets) == "table" and #extra_data.must_targets > 0 and
            not table.contains(extra_data.must_targets, p.id) then
          return false
        end
        if type(extra_data.exclusive_targets) == "table" and #extra_data.exclusive_targets > 0 and
            not table.contains(extra_data.exclusive_targets, p.id) then
          return false
        end
      end
      return not player:isProhibited(p, card) and card.skill:modTargetFilter(player, p, {}, card, extra_data)
    end
    local findCardTarget = function(card)
      local tos = {}
      for _, p in ipairs(room.alive_players) do
        if isAvailableTarget(card, p) then
          table.insert(tos, p)
        end
      end
      return tos
    end
    names = table.filter(names, function (c_name)
      local card = Fk:cloneCard(c_name)
      return not player:prohibitUse(card) and (card.skill:getMinTargetNum(player) == 0 or #findCardTarget(card) > 0)
    end)
    if #names == 0 then return false end
    local name = room:askToChoice(player, { choices = names, skill_name = skillName, prompt = "#mou__rende-name" })
    player:broadcastSkillInvoke(skillName)
    local card = Fk:cloneCard(name)
    card.skillName = skillName
    data.result = {
      from = player,
      card = card,
    }
    if card.skill:getMinTargetNum(player) == 1 then
      local tos = findCardTarget(card)
      if #tos == 1 then
        data.result.tos = tos
      elseif #tos > 1 then
        data.result.tos = room:askToChoosePlayers(
          player,
          {
            targets = tos,
            min_num = 1,
            max_num = 1,
            prompt = "#mou__rende-target:::" .. name,
            skill_name = skillName,
            cancelable = false,
            no_indicate = true
          }
        )
      else
        return false
      end
    end
    if data.eventData then
      data.result.toCard = data.eventData.toCard
      data.result.responseToEvent = data.eventData.responseToEvent
    end
    return true
  end
})

shenji:addEffect(fk.AskForCardResponse, {
  mute = true,
  can_trigger = shenji__TriggerViewAsCanTrigger,
  on_cost = shenji__TriggerViewAsOnCost,
  on_use = function(self, event, target, player, data)
    ---@type string
    local skillName = shenji.name
    local room = player.room
    local names = event:getCostData(self)
    names = table.filter(names, function (c_name)
      return not player:prohibitResponse(Fk:cloneCard(c_name))
    end)
    if #names == 0 then return false end
    local name = room:askToChoice(player, { choices = names, skill_name = skillName, prompt = "#mou__rende-name" })
    player:broadcastSkillInvoke(skillName)
    local card = Fk:cloneCard(name)
    card.skillName = skillName
    card.subcards = {}
    data.result = {
      from = player,
      card = card,
    }
    return true
  end
})


return shenji
